package com.gcit.seniorWish.web.modular.system.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.mapper.Condition;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.gcit.seniorWish.web.core.annotion.BussinessLog;
import com.gcit.seniorWish.web.core.annotion.Permission;
import com.gcit.seniorWish.web.common.constant.Const;
import com.gcit.seniorWish.web.common.constant.dictmap.UserDict;
import com.gcit.seniorWish.web.common.constant.factory.ConstantFactory;
import com.gcit.seniorWish.web.common.constant.enums.ManagerStatusEnum;
import com.gcit.seniorWish.web.common.constant.enums.RoleEnum;
import com.gcit.seniorWish.web.common.constant.enums.UserTypeEnum;
import com.gcit.seniorWish.web.common.constant.factory.PageFactory;
import com.gcit.seniorWish.web.core.exception.BizExceptionEnum;
import com.gcit.seniorWish.web.common.persistence.dao.UserMapper;
import com.gcit.seniorWish.web.common.persistence.model.Role;
import com.gcit.seniorWish.web.common.persistence.model.User;
import com.gcit.seniorWish.core.base.controller.BaseController;
import com.gcit.seniorWish.core.base.tips.Tip;
import com.gcit.seniorWish.core.exception.GunsException;
import com.gcit.seniorWish.web.core.log.LogObjectHolder;
import com.gcit.seniorWish.web.core.shiro.ShiroKit;
import com.gcit.seniorWish.core.util.ToolUtil;
import com.gcit.seniorWish.web.modular.examinee.service.ISeniorSchoolClassService;
import com.gcit.seniorWish.web.modular.examinee.service.ISeniorSchoolService;
import com.gcit.seniorWish.web.modular.system.service.IRoleService;
import com.gcit.seniorWish.web.modular.system.service.IUserMgrService;
import com.gcit.seniorWish.web.modular.system.warpper.UserWarpper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 系统管理员控制器
 *
 * @author fengshuonan
 * @Date 2017年1月11日 下午1:08:17
 */
@Controller
@RequestMapping("/mgr")
public class UserMgrController extends BaseController {

	private static String PREFIX = "/system/user";

	@Resource
	private UserMapper userMapper;

	@Autowired
	private IUserMgrService userMgrService;

	@Autowired
	private ISeniorSchoolClassService seniorSchoolClassService;

	@Autowired
	ISeniorSchoolService seniorSchoolService;

	@Autowired
	IRoleService roleService;

	/**
	 * 跳转到查看管理员列表的页面
	 */
	@RequestMapping("")
	public String index() {
		return PREFIX + "/user.html";
	}

	/**
	 * 跳转到查看管理员列表的页面
	 */
	@RequestMapping("/userAdd")
	public String addView(Model model) {
		if (UserTypeEnum.TEACHING.getValue() == ShiroKit.getUser().getType()) {// 登录人为班主任
			model.addAttribute("schoolu", seniorSchoolService.listSchoolForSelect2(null,ShiroKit.getUser().getSchoolId()));
			model.addAttribute("classu", seniorSchoolClassService
					.listSchoolClassForSelect2(null,ShiroKit.getUser().getSchoolId(), ShiroKit.getUser().getClassId()));
		} else if (UserTypeEnum.SCHOOL.getValue() == ShiroKit.getUser().getType()) {// 登录人为学校管理员
			model.addAttribute("schoolu", seniorSchoolService.listSchoolForSelect2(null,ShiroKit.getUser().getSchoolId()));
			model.addAttribute("classu", null);
		} else {
			model.addAttribute("schoolu", null);
			model.addAttribute("classu", null);
		}
		return PREFIX + "/userAdd.html";
	}

	/**
	 * 跳转到角色分配页面
	 */
	@SuppressWarnings("unchecked")
	// @RequiresPermissions("/mgr/role_assign") //利用shiro自带的权限检查
	@RequestMapping("/roleAssign/{userId}")
	public String roleAssign(@PathVariable String userId, Model model) {
		if (ToolUtil.isEmpty(userId)) {
			throw new GunsException(BizExceptionEnum.REQUEST_NULL);
		}
		User user = userMgrService.selectOne(Condition.create().eq("id", userId));
		model.addAttribute("userId", userId);
		model.addAttribute("userAccount", user.getAccount());
		return PREFIX + "/userRoleAssign.html";
	}

	/**
	 * 跳转到编辑管理员页面
	 */
	@RequestMapping("/userEdit/{userId}")
	public String userEdit(@PathVariable String userId, Model model) {
		if (ToolUtil.isEmpty(userId)) {
			throw new GunsException(BizExceptionEnum.REQUEST_NULL);
		}
		assertAuth(userId);
		User user = this.userMapper.selectById(userId);
		model.addAttribute(user);
		model.addAttribute("roleName", ConstantFactory.me().getRoleName(user.getId()));
		LogObjectHolder.me().set(user);
		return PREFIX + "/userInfo.html";
	}

	/**
	 * 跳转到查看用户详情页面
	 */
	@RequestMapping("/userView")
	public String userInfo(Model model) {
		String userId = ShiroKit.getUser().getId();
		if (ToolUtil.isEmpty(userId)) {
			throw new GunsException(BizExceptionEnum.REQUEST_NULL);
		}
		User user = this.userMapper.selectById(userId);
		model.addAttribute(user);
		model.addAttribute("roleName", ConstantFactory.me().getRoleName(user.getId()));
		model.addAttribute("deptName", ConstantFactory.me().getDeptName(user.getDeptId()));
		LogObjectHolder.me().set(user);
		return PREFIX + "/user_view.html";
	}

	/**
	 * 跳转到修改密码界面
	 */
	@RequestMapping("/user_chpwd")
	public String chPwd() {
		return PREFIX + "/user_chpwd.html";
	}

	/**
	 * 修改当前用户的密码
	 */
	@RequestMapping("/changePwd")
	@ResponseBody
	public Object changePwd(@RequestParam String oldPwd, @RequestParam String newPwd, @RequestParam String rePwd) {
		if (!newPwd.equals(rePwd)) {
			throw new GunsException(BizExceptionEnum.TWO_PWD_NOT_MATCH);
		}
		String userId = ShiroKit.getUser().getId();
		User user = userMapper.selectById(userId);
		String oldMd5 = ShiroKit.md5(oldPwd, user.getSalt());
		if (user.getPassword().equals(oldMd5)) {
			String newMd5 = ShiroKit.md5(newPwd, user.getSalt());
			user.setPassword(newMd5);
			user.updateById();
			return SUCCESS_TIP;
		} else {
			throw new GunsException(BizExceptionEnum.OLD_PWD_NOT_RIGHT);
		}
	}

	/**
	 * 查询管理员列表
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping("/list")
	@ResponseBody
	public Object list(String name, Date startTime, Date endTime, String deptId) {
		EntityWrapper<User> ew = new EntityWrapper<User>();
		Page<Map<String, Object>> page = new PageFactory<Map<String, Object>>().defaultPage();
		// 添加查询条件
		if (startTime != null) {
			ew.ge("create_time", startTime);
		}
		if (endTime != null) {
			ew.le("create_time", endTime);
		}
		// 查询指定部门及子部门的用户
//		if (StrUtil.isNotBlank(deptId)) {
//			ew.in("dept_id", ConstantFactory.me().getSubdeptId(deptId, true));
//		}
		if (UserTypeEnum.TEACHING.getValue() == ShiroKit.getUser().getType()) {// 登录人为班主任
			ew.eq("school_id", ShiroKit.getUser().getSchoolId());
			ew.eq("class_id", ShiroKit.getUser().getClassId());
		} else if (UserTypeEnum.SCHOOL.getValue() == ShiroKit.getUser().getType()) {// 登录人为学校管理员
			ew.eq("school_id", ShiroKit.getUser().getSchoolId());
		}
		//后台管理不查询学生类型的用户
		ew.ne("type",UserTypeEnum.EXAMINEE.getValue());
		if (StrUtil.isNotBlank(name)) {
			ew.andNew().like("name", name).or().like("account", name);
		}
		page = userMgrService.selectMapsPage(page, ew);
		page.setRecords((List<Map<String, Object>>) new UserWarpper(page.getRecords()).warp());
		return packForBT(page);
	}

	/**
	 * 添加管理员
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping("/add")
	@BussinessLog(value = "添加管理员", key = "account", dict = UserDict.class)
	@ResponseBody
	public Tip add(User user, BindingResult result) {
		// 判断账号是否重复
		if (userMgrService.selectCount(Condition.create().eq("account", user.getAccount())) > 0) {
			throw new GunsException(BizExceptionEnum.USER_ALREADY_REG);
		}
		// 完善账号信息
		if (!StrUtil.isBlank(user.getClassId())) {// 表示添加的是班主任用户
			user.setType(UserTypeEnum.TEACHING.getValue());
		} else if (!StrUtil.isBlank(user.getSchoolId()) && StrUtil.isBlank(user.getClassId())) {// 添加的是学校管理员用户
			user.setType(UserTypeEnum.SCHOOL.getValue());
		} else {//系统管理员
			user.setType(UserTypeEnum.SYSTEM.getValue());
		}
		user.setSalt(ShiroKit.getRandomSalt(5));
		user.setPassword(ShiroKit.md5(user.getPassword(), user.getSalt()));
		user.setDeptId(Const.DEFAULT_DEPT_ID);
		user.setStatus(ManagerStatusEnum.ABLE.getCode());
		this.userMgrService.insert(user);
		if (!StrUtil.isBlank(user.getClassId())) {// 表示添加的是班主任用户
			Role role = roleService.selectOne(Condition.create().eq("name", RoleEnum.CLASS_TEACHER.getDes()));
			userMgrService.setRoles(user.getId(), role.getId());
		} else if (!StrUtil.isBlank(user.getSchoolId()) && StrUtil.isBlank(user.getClassId())) {// 添加的是学校管理员用户
			Role role = roleService.selectOne(Condition.create().eq("name", RoleEnum.SCHOOL_ADMIN.getDes()));
			userMgrService.setRoles(user.getId(), role.getId());
		}else{
			Role role = roleService.selectOne(Condition.create().eq("name", RoleEnum.ADMIN.getDes()));
			userMgrService.setRoles(user.getId(), role.getId());
		}
		return SUCCESS_TIP;
	}

	/**
	 * 修改管理员
	 *
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping("/edit")
	@BussinessLog(value = "修改管理员", key = "account", dict = UserDict.class)
	@ResponseBody
	public Tip edit(User user) {
		// 判断账号是否重复
		if (userMgrService
				.selectCount(Condition.create().ne("id", user.getId()).eq("account", user.getAccount())) > 0) {
			throw new GunsException(BizExceptionEnum.USER_ALREADY_REG);
		}
		this.userMapper.updateById(user);
		return SUCCESS_TIP;
	}

	/**
	 * 删除管理员（逻辑删除）
	 */
	@RequestMapping("/delete")
	@BussinessLog(value = "删除管理员", key = "userId", dict = UserDict.class)
	@ResponseBody
	public Tip delete(@RequestParam String userId) {
		if (ToolUtil.isEmpty(userId)) {
			throw new GunsException(BizExceptionEnum.REQUEST_NULL);
		}
		// 不能删除超级管理员
		if (userId.equals(Const.ADMIN_ID)) {
			throw new GunsException(BizExceptionEnum.CANT_DELETE_ADMIN);
		}
		assertAuth(userId);
		this.userMgrService.deleteUser(userId);
		return SUCCESS_TIP;
	}

	/**
	 * 查看管理员详情
	 */
	@RequestMapping("/WEB-INF/view/{userId}")
	@ResponseBody
	public User view(@PathVariable String userId) {
		if (ToolUtil.isEmpty(userId)) {
			throw new GunsException(BizExceptionEnum.REQUEST_NULL);
		}
		assertAuth(userId);
		return this.userMapper.selectById(userId);
	}

	/**
	 * 重置管理员的密码
	 */
	@RequestMapping("/reset")
	@BussinessLog(value = "重置管理员密码", key = "userId", dict = UserDict.class)
	@ResponseBody
	public Tip reset(@RequestParam String userId) {
		if (ToolUtil.isEmpty(userId)) {
			throw new GunsException(BizExceptionEnum.REQUEST_NULL);
		}
		assertAuth(userId);
		User user = this.userMapper.selectById(userId);
		user.setSalt(ShiroKit.getRandomSalt(5));
		user.setPassword(ShiroKit.md5(Const.DEFAULT_PWD, user.getSalt()));
		this.userMapper.updateById(user);
		return SUCCESS_TIP;
	}

	/**
	 * 冻结用户
	 */
	@RequestMapping("/freeze")
	@BussinessLog(value = "冻结用户", key = "userId", dict = UserDict.class)
	@ResponseBody
	public Tip freeze(@RequestParam String userId) {
		if (ToolUtil.isEmpty(userId)) {
			throw new GunsException(BizExceptionEnum.REQUEST_NULL);
		}
		// 不能冻结超级管理员
		if (userId.equals(Const.ADMIN_ID)) {
			throw new GunsException(BizExceptionEnum.CANT_FREEZE_ADMIN);
		}
		assertAuth(userId);
		// 设置状态
		User temp = new User();
		temp.setId(userId);
		temp.setStatus(ManagerStatusEnum.FREEZE.getCode());
		userMgrService.updateById(temp);
		return SUCCESS_TIP;
	}

	/**
	 * 解除冻结用户
	 */
	@RequestMapping("/unfreeze")
	@BussinessLog(value = "解除冻结用户", key = "userId", dict = UserDict.class)
	@ResponseBody
	public Tip unfreeze(@RequestParam String userId) {
		if (ToolUtil.isEmpty(userId)) {
			throw new GunsException(BizExceptionEnum.REQUEST_NULL);
		}
		assertAuth(userId);
		// 设置状态
		User temp = new User();
		temp.setId(userId);
		temp.setStatus(ManagerStatusEnum.ABLE.getCode());
		userMgrService.updateById(temp);
		return SUCCESS_TIP;
	}

	/**
	 * 分配角色
	 */
	@RequestMapping("/setRole")
	@BussinessLog(value = "分配角色", key = "userId,roleIds", dict = UserDict.class)
	@ResponseBody
	public Tip setRole(@RequestParam("userId") String userId, @RequestParam("roleIds") String roleIds) {
		if (ToolUtil.isOneEmpty(userId, roleIds)) {
			throw new GunsException(BizExceptionEnum.REQUEST_NULL);
		}
		// 不能修改超级管理员
		if (userId.equals(Const.ADMIN_ID)) {
			throw new GunsException(BizExceptionEnum.CANT_CHANGE_ADMIN);
		}
		assertAuth(userId);
		this.userMgrService.setRoles(userId, roleIds);
		return SUCCESS_TIP;
	}

	/**
	 * 判断当前登录的用户是否有操作这个用户的权限
	 */
	private void assertAuth(String userId) {
		// 本项目去除部门认证。只要有修改用户的权限就可以修改用户
		// if (ShiroKit.isAdmin()) {
		// return;
		// }
		// List<String> deptDataScope = ShiroKit.getDeptDataScope();
		// User user = this.userMapper.selectById(userId);
		// String deptId = user.getDeptId();
		// if (deptDataScope == null || deptDataScope.contains(deptId)) {
		// return;
		// } else {
		// throw new GunsException(BizExceptionEnum.NO_PERMITION);
		// }
	}
}
